﻿package fj.net
{
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.utils.ByteArray;
	import flash.utils.Endian;

	public class FJUploadFile
	{

		/**
		 * Uploads a file using a given URLLoader object.
		 * 
		 * @param loader The URLLoader object to use
		 * @param url The location of the script recieving the upload
		 * @param file The file to upload
		 * @param fileName The name of the file
		 * @param contentType The content-type of the file
		 */
		public static function upload( loader: URLLoader, url: String, file: ByteArray, fileName: String, contentType: String = 'application/octet-stream' ):void
		{
			var i: int;
			var boundary: String = '--';
			var request: URLRequest = new URLRequest;
			var postData: ByteArray = new ByteArray;
			var bytes: String;

			for (i = 0; i < 0x10; i++) {
				boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
			}

			loader.dataFormat = URLLoaderDataFormat.BINARY;

			request.url = url;
			request.contentType = 'multipart/form-data; boundary=' + boundary;
			request.method = URLRequestMethod.POST;

			postData.endian = Endian.BIG_ENDIAN;

			postData.writeShort( 0x2d2d );
			for (i = 0; i < boundary.length; i++) {
				postData.writeByte( boundary.charCodeAt( i ) );
			}

			postData.writeShort( 0x0d0a );

			bytes = 'Content-Disposition: form-data; name="Filename"';
			for (i = 0; i < bytes.length; i++) {
				postData.writeByte( bytes.charCodeAt( i ) );
			}

			postData.writeInt( 0x0d0a0d0a );

			postData.writeUTFBytes( fileName );

			postData.writeShort( 0x0d0a );

			postData.writeShort( 0x2d2d );
			for (i = 0; i < boundary.length; i++) {
				postData.writeByte( boundary.charCodeAt( i ) );
			}

			postData.writeShort( 0x0d0a );

			bytes = 'Content-Disposition: form-data; name="Filedata"; filename="';
			for (i = 0; i < bytes.length; i++) {
				postData.writeByte( bytes.charCodeAt( i ) );
			}

			postData.writeUTFBytes( fileName );

			postData.writeByte( 0x22 );

			postData.writeShort( 0x0d0a );

			bytes = 'Content-Type: ' + contentType;
			for (i = 0; i < bytes.length; i++) {
				postData.writeByte( bytes.charCodeAt( i ) );
			}

			postData.writeInt( 0x0d0a0d0a );

			postData.writeBytes( file, 0, file.length );

			postData.writeShort( 0x0d0a );

			postData.writeShort( 0x2d2d );
			for (i = 0; i < boundary.length; i++) {
				postData.writeByte( boundary.charCodeAt( i ) );
			}

			postData.writeShort( 0x0d0a );

			bytes = 'Content-Disposition: form-data; name="Upload"';
			for (i = 0; i < bytes.length; i++) {
				postData.writeByte( bytes.charCodeAt( i ) );
			}

			postData.writeInt( 0x0d0a0d0a );

			bytes = 'Submit Query';
			for (i = 0; i < bytes.length; i++) {
				postData.writeByte( bytes.charCodeAt( i ) );
			}

			postData.writeShort( 0x0d0a );

			postData.writeShort( 0x2d2d );
			for (i = 0; i < boundary.length; i++) {
				postData.writeByte( boundary.charCodeAt( i ) );
			}
			postData.writeShort( 0x2d2d );

			request.data = postData;
			request.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
			loader.load( request );
		}
	}
}